﻿/*
 * Создан: Оникийчук Антон Игоревич
 * Компания: ООО "ИМСАТ"
 * Дата создания: 21.01.2009
 * Время создания: 10:03
 * Emal разработчика: onikiychuka@gmail.com
 */
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;

namespace IMSAT.OFTD.DOM
{
    /// <summary>
    /// Description of Document.
    /// </summary>
    public class Document : Node//, IDocument
    {
        private static bool inited;
        private readonly PropertyCollection _attributes;
        private readonly PageCollection _pages;
        private string _commonImageData = "";

        public Document()
        {
            //InitReaders();
            _pages = new PageCollection(ChildNodes);
            _attributes = new PropertyCollection(ChildNodes);
        }

        /// <summary>
        /// Страницы документа
        /// </summary>
        public PageCollection Pages
        {
            get { return _pages; }
        }

        /// <summary>
        /// Аттрибуты документа
        /// </summary>
        public PropertyCollection Attributes
        {
            get { return _attributes; }
        }

        /// <summary>
        /// Общие данные о изображение стили, сойства итд.
        /// </summary>
        public string CommonImageData
        {
            get { return _commonImageData; }
        }

        protected static void InitReaders()
        {
            if (inited) return;
            var rw = RWHolder.GetInstace();
            foreach (var type in rw.GetType().Assembly.GetTypes())
                if (type.IsSubclassOf(typeof(Node)))
                    foreach (var nested in type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic))
                        foreach (var iface in nested.GetInterfaces())
                            if (iface.FullName == typeof(IReader).FullName) 
                                rw.RegisterReader(nested.GetConstructor(Type.EmptyTypes).Invoke(null) as IReader);
                        
                
            /*
                rw.RegisterReader(new Reader());
                rw.RegisterReader(new Layer.Reader());
                rw.RegisterReader(new SvgNode.Reader());
                rw.RegisterReader(new NodeXmlReader());
                rw.RegisterReader(new Element.Reader());
                rw.RegisterReader(new Link.Reader());
                rw.RegisterReader(new Property.Reader());
                rw.RegisterReader(new TextProperty.TextPropertyXmlReader());
                rw.RegisterReader(new Page.Reader());//*/
            inited = true;
        }

        /// <summary>
        /// Загрузить документ из файла
        /// </summary>
        /// <param name="fname">имя файла</param>
        /// <returns></returns>
        public static Document Load(string fname)
        {            
            InitReaders();
            using (XmlReader rd = XmlReader.Create(fname))
            {
                while (rd.Read())
                {
                    if (rd.NodeType == XmlNodeType.Element) break;
                }                
                IReader r = (RWHolder.GetInstace().GetReader(typeof(Node), rd.ReadSubtree(), null));                
                Document d = r.Read(rd.ReadSubtree()) as Document;                
                return d;
                
            }
            
        }

        public static Document Load(Stream inStream)
        {
            InitReaders();
            using (XmlReader rd = XmlReader.Create(inStream))
            {
                while (rd.Read())
                {
                    if (rd.NodeType == XmlNodeType.Element) break;
                }
                return
                    (RWHolder.GetInstace().GetReader(typeof (Node), rd.ReadSubtree(), null).Read(rd.ReadSubtree()) as Document);
            }
        }

        #region Nested type: Reader

        public class Reader : NodeXmlReader
        {
            protected override bool CheckReader(XmlReader rd, bool _prevRes, Node parentNode)
            {
                if (_prevRes)
                {
                    if (rd.LocalName == "Документ")
                    {
                        return true;
                    }
                    return false;
                }
                return base.CheckReader(rd, _prevRes, parentNode);
            }

            protected override Node InitNode(XmlReader reader, Node initedNode)
            {
                if (initedNode == null)
                    initedNode = new Document();
                var d = (Document) initedNode;

                return base.InitNode(reader, initedNode);
            }

            protected override Node InitObjectAfterBuild(Node result)
            {
                return base.InitObjectAfterBuild(result);
            }
        }

        #endregion
    }
}